/*
 - Creater: Nguyen Ngoc An
 - Mail: annn@nct.vn
 - Date: 7/9/2014
 */
package org.nct.cached;

import org.nct.StaticVariable.StaticVariable;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.nct.BlockingQueue.BlockingQueueMemCached;
import org.nct.Interface.IAction;
import org.nct.cachedclient.CachedClient;
import org.nct.config.Config;
import org.nct.event.DeleteMemCachedEvent;
import org.nct.event.GetMemCachedEvent;
import org.nct.event.SetMemCachedEvent;
import org.nct.handler.MemCachedHandler;

/**
 *
 * @author annn
 */
public final class Cached implements IAction, Runnable {

    private static Cached _Instance;
    private BlockingQueueMemCached queue = null;
    private CachedClient[] clients = null;

    public synchronized static Cached getInstance() throws IOException {
        if (_Instance == null) {
            return _Instance = new Cached();
        }
        return _Instance;
    }

    public Cached() throws IOException {
        //Doc config
        StaticVariable.expires = Integer.parseInt(Config.getInstance().getPropValues("expires"));
        StaticVariable.menmory = Long.parseLong(Config.getInstance().getPropValues("menmory"));
        StaticVariable.hosts = Config.getInstance().getPropValues("hosts");
        StaticVariable.username = Config.getInstance().getPropValues("username");
        StaticVariable.password = Config.getInstance().getPropValues("password");
        StaticVariable.countconnection = Integer.parseInt(Config.getInstance().getPropValues("countconnection"));
        StaticVariable.sizequeue = Integer.parseInt(Config.getInstance().getPropValues("sizequeue"));

        //Init
        queue = new BlockingQueueMemCached();
        clients = new CachedClient[StaticVariable.countconnection];

        for (int i = 0; i < StaticVariable.countconnection; i++) {
            clients[i] = new CachedClient(i);
        }
    }
    int k = 0;

    @Override
    public void Get(Object obj) {
        int i = (int) (k++ % (StaticVariable.countconnection));

        MemCachedHandler h = (MemCachedHandler) obj;
        GetMemCachedEvent thread = new GetMemCachedEvent(clients[i], h);
        try {
            queue.Add(thread);
        } catch (InterruptedException ex) {
            Logger.getLogger(Cached.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void Set(Object obj) {
        int i = (int) (k++ % (StaticVariable.countconnection ));
        MemCachedHandler h = (MemCachedHandler) obj;
        SetMemCachedEvent thread = new SetMemCachedEvent(clients[i], h);
        try {
            queue.Add(thread);
        } catch (InterruptedException ex) {
            Logger.getLogger(Cached.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void Delete(Object obj) {
        int i = (int) (k++ % (StaticVariable.countconnection ));

        MemCachedHandler h = (MemCachedHandler) obj;
        DeleteMemCachedEvent thread = new DeleteMemCachedEvent(clients[i], h);
        try {
            queue.Add(thread);
        } catch (InterruptedException ex) {
            Logger.getLogger(Cached.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void run() {
        while (true) {
            if (!queue.isEmpty()) {
                try {
                    Thread th = new Thread((Runnable) queue.Get());
                    th.start();
                } catch (InterruptedException ex) {
                    Logger.getLogger(Cached.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {

            }
        }
    }

}
